/**
 * Marcelo A Nagatomo
 * RA 062689
 * Atividade 1 - 14-09-2009
 */


/***************************************************************************/
/****   SERVIDOR  **********************************************************/
/***************************************************************************/




#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>

#define LISTENQ 10
#define MAXDATASIZE 100

int main (int argc, char **argv) {
   int    listenfd, connfd;
   struct sockaddr_in servaddr;
   char   buf[MAXDATASIZE];
   time_t ticks;

   // Starting a socket with TCPv4, TCP for commons appplications
   if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
     // SocketError Handling
      perror("socket");
      exit(1);
   }

   // allocates the memory with '0'
   bzero(&servaddr, sizeof(servaddr));
   
   servaddr.sin_family      = AF_INET; 				// Internet family
   servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 	// IP address
   servaddr.sin_port        = htons(3000);   		//** Port: modified line in ex4**//

   // Assign a IP address at socket door created.
   if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
      perror("bind");
      exit(1);
   }
   
   // marks the socket referred to by 'listenfd' as a passive socket, that is, as a socket that will
   // be used to accept incoming connection requests using accept.
   if (listen(listenfd, LISTENQ) == -1) {
      perror("listen");
      exit(1);
   }

   struct sockaddr_in clientaddr;
   socklen_t clientaddr_len = sizeof(clientaddr);
   for ( ; ; ) {
     
      // Get data and remove first connection of stack.
      if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) == -1 ) {
         perror("accept");
         exit(1);
      }
      
	  if (getpeername(connfd, (struct sockaddr *) &clientaddr, &clientaddr_len) >= 0){
		char* ipAddr = inet_ntoa(clientaddr.sin_addr);
		printf("Client IP address is: %s\n", ipAddr);
		printf("Client Port is: %d\n", (int) ntohs(clientaddr.sin_port));

      } else {
		perror("getpeername() error)");
        exit(1);
	  
	  }
      
      ticks = time(NULL);
      snprintf(buf, sizeof(buf), "%.24s\r\n", ctime(&ticks));
      
	  // Send the msg 'buf' to client on opened connection.
      write(connfd, buf, strlen(buf));

	  sleep(10);
	  
      // Close conection.
      close(connfd);
   }
   return(0);
}
